package com.niiwoo.civet.user.service.local;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.service.AccountCompanyDubboService;
import com.niiwoo.civet.user.dao.entity.*;
import com.niiwoo.civet.user.dao.mapper.*;
import com.niiwoo.civet.user.dto.request.UserAuthorizationInfoDTO;
import com.niiwoo.civet.user.dto.response.UserAuthorizationInfoResponseDTO;
import com.niiwoo.civet.user.enums.UserDataStatusEnum;
import com.niiwoo.civet.user.enums.UserDataTypeEnum;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.utils.FutureResponses;
import com.niiwoo.tripod.fadada.FadadaService;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.fadada.enums.FadadaAuthCodeEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @Author: wuke
 * @Description:
 * @Date: Created in 16:00 2017/11/16
 */
@Slf4j
@Service
public class UserAuthorizationInfoService {

    @Autowired
    private UserAuthorizationInfoMapperExt userAuthorizationInfoMapper;
    @Autowired
    private UserBasicInfoMapperExt userBasicInfoMapper;
    @Autowired
    private IdentityInfoMapperExt ucIdentityInfoMapper;
    @Autowired
    private DataStatusMapperExt dataStatusMapper;
    @Autowired
    private FadadaService fadadaService;
    @Autowired
    private PrivacyMasks privacyMasks;
    @Autowired
    private UserStatusService userStatusService;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private OrganizationInfoMapperExt organizationInfoMapperExt;
    @Reference(version = "1.0.0")
    private AccountCompanyDubboService accountCompanyDubboService;

    public UserAuthorizationInfoResponseDTO getUserAuthorizationInfo(String userId) {
        UserAuthorizationInfo userAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);
        if (userAuthorizationInfo == null) {
            return null;
        }

        UserAuthorizationInfoResponseDTO responseDTO = new UserAuthorizationInfoResponseDTO();
        BeanUtils.copyProperties(userAuthorizationInfo, responseDTO);

        return responseDTO;
    }

    public List<UserAuthorizationInfoResponseDTO> queryUserAuthorizationInfoListByUserIdSet(Set<String> userIdSet) {
        List<UserAuthorizationInfoResponseDTO> result = new ArrayList<UserAuthorizationInfoResponseDTO>();
        List<UserAuthorizationInfo> userAuthorizationInfoList = userAuthorizationInfoMapper
                .queryUserAuthorizationInfoListByUserIdSet(userIdSet);
        for (UserAuthorizationInfo userAuthorizationInfo : userAuthorizationInfoList) {
            UserAuthorizationInfoResponseDTO dto = new UserAuthorizationInfoResponseDTO();
            BeanUtils.copyProperties(userAuthorizationInfo, dto);
            result.add(dto);
        }

        return result;
    }

    /**
     * 法大大授权
     *
     * @param userId
     */
    public String fadadaAuth(String userId) {
        UserAuthorizationInfo userAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);
        if (userAuthorizationInfo != null && StringUtils.hasText(userAuthorizationInfo.getFadadaCacertId())) {
            return userAuthorizationInfo.getFadadaCacertId();
        }

        //获取用户基本信息
        UserBasicInfo userBasicInfo = userBasicInfoMapper.selectByPrimaryKey(userId);
        if (userBasicInfo == null) {
            throw new BizException("USR10004");
        }

        //获取用户身份证信息
        IdentityInfo identityInfo = ucIdentityInfoMapper.selectByPrimaryKey(userId);
        if (identityInfo == null) {
            throw new BizException("USR11006");
        }

        //获取用户名、身份证号、手机号并解密
        String name = identityInfo.getName();
        String idCard = identityInfo.getIdCard();
        String mobileNo = userBasicInfo.getMobileNo();
        idCard = privacyMasks.decryptPrivacy(idCard);
        mobileNo = privacyMasks.decryptPrivacy(mobileNo);
        try {
            //调用法大大接口
            log.info("fadadaService.syncPersonAuto name={},idCard={},mobileNo={}", name, idCard, mobileNo);
            CompletableFuture<FadadaResponseDTO> fadadaResultFuture = fadadaService.syncPersonAuto(name, idCard, mobileNo, null);
            log.info("fadadaService.syncPersonAuto name={},idCard={},mobileNo={},fadadaResultFuture={}", name, idCard, mobileNo, JSON.toJSONString(fadadaResultFuture));
//            FadadaResponseDTO fadadaResult = FutureResponses.get(fadadaResultFuture);
            FadadaResponseDTO fadadaResult = fadadaResultFuture.get(5, TimeUnit.SECONDS);
            String result = fadadaResult.getResult();
            String code = fadadaResult.getCode();
            String msg = fadadaResult.getMsg();
            if ("success".equals(result) && "1000".equals(code)) {
                String customerId = fadadaResult.getCustomerId();
                getSelfProxy().fadadaAuthSuccessResultDeal(userId, customerId);
                return customerId;
            } else {
                throw new BizException("USR11007", this.getFadadaAuthErrorMsg(code, msg));
            }
        } catch (Exception ex) {
            log.error("个人法大大异常{}", ex);
            throw new BizException("USR11007");
        }
    }

    /**
     * 企业法大大授权
     *
     * @param orgId
     * @return
     */
    public String fadadaEnterAuth(String orgId) {

        OrganizationInfo organizationInfo = organizationInfoMapperExt.selectByPrimaryKey(orgId);

        log.info("fadadaEnterAuth.orgId={},organizationInfo={}",orgId,JSON.toJSONString(organizationInfo));

        if (organizationInfo == null) {
            throw new BizException("USR11011");
        }

        if(!StringUtils.isEmpty(organizationInfo.getFadadaCacertId())){
            return organizationInfo.getFadadaCacertId();
        }
        //获取用户名、身份证号、手机号并解密
        String name = organizationInfo.getOrganizationName();
        String unifiedSocialCreditCode = organizationInfo.getUnifiedSocialCreditCode();
        String organizationCode = StringUtils.hasText(unifiedSocialCreditCode)?unifiedSocialCreditCode:organizationInfo.getOrgNo();
        String mobileNo = organizationInfo.getLegalPersonPhoneNumber();
//        String email = organizationInfo.getEmail();
        if (StringUtils.isEmpty(mobileNo)) {
            throw new BizException("USR11013");
        }
        try {
            mobileNo = privacyMasks.decryptPrivacy(mobileNo);
        } catch (Exception ex) {
            log.error("企业法大大授权-法人手机号解密报错", ex);
        }
        //调用法大大接口
        log.info("企业法大大授权fadadaService.fadadaEnterAuth name={},organizationCode={},mobileNo={}", name, organizationCode, mobileNo);
        CompletableFuture<FadadaResponseDTO> fadadaResultFuture = fadadaService.syncCompanyPlus(name, organizationCode, mobileNo);
        FadadaResponseDTO fadadaResult = FutureResponses.get(fadadaResultFuture);
        log.info("企业法大大授权fadadaResult={}", JSON.toJSONString(fadadaResult));
        String result = fadadaResult.getResult();
        String code = fadadaResult.getCode();
        String msg = fadadaResult.getMsg();
        if ("success".equals(result) && "1000".equals(code)) {
            log.info("企业法大大授权成功code={},result = {}", code, result);
            String customerId = fadadaResult.getCustomerId();
            getSelfProxy().fadadaAuthEnterSuccessResult(organizationInfo, customerId);
            return customerId;
        } else {
            throw new BizException("USR11010", this.getFadadaAuthErrorMsg(code, msg));
        }
    }

    private String getFadadaAuthErrorMsg(String code, String msg) {
        if (!StringUtils.hasText(code)) {
            return msg;
        }
        FadadaAuthCodeEnum fadadaAuthCodeEnum = FadadaAuthCodeEnum.enumOf(code);
        if (fadadaAuthCodeEnum == null || FadadaAuthCodeEnum.BUSINESS_ERROR.getCode().equals(code)) {
            return msg;
        }
        return fadadaAuthCodeEnum.getDesc();
    }

    /**
     * 卡牛法大大授权
     *
     * @param userId
     * @return
     */
    public String cardniuFadadaAuth(String userId) {
        log.info("用户中心卡牛法大大授权userId = {}", userId);
        UserAuthorizationInfo userAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);
        if (userAuthorizationInfo != null && StringUtils.hasText(userAuthorizationInfo.getFadadaCacertId())) {
            return userAuthorizationInfo.getFadadaCacertId();
        }

        //获取用户基本信息
        UserBasicInfo userBasicInfo = userBasicInfoMapper.selectByPrimaryKey(userId);
        if (userBasicInfo == null) {
            throw new BizException("USR10004");
        }

        //获取用户身份证信息
        IdentityInfo identityInfo = ucIdentityInfoMapper.selectByPrimaryKey(userId);
        if (identityInfo == null) {
            throw new BizException("USR11006");
        }

        //获取用户名、身份证号、手机号并解密
        String name = identityInfo.getName();
        String idCard = identityInfo.getIdCard();
        String mobileNo = userBasicInfo.getMobileNo();
        idCard = privacyMasks.decryptPrivacy(idCard);
        mobileNo = privacyMasks.decryptPrivacy(mobileNo);

        //调用法大大接口
        log.info("fadadaService.syncPersonAuto name={},idCard={},mobileNo={}", name, idCard, mobileNo);
        CompletableFuture<FadadaResponseDTO> fadadaResultFuture = fadadaService.syncPersonAuto(name, idCard, mobileNo, null);
        log.info("fadadaService.syncPersonAuto name={},idCard={},mobileNo={},fadadaResultFuture={}", name, idCard, mobileNo, JSON.toJSONString(fadadaResultFuture));
        FadadaResponseDTO fadadaResult = FutureResponses.get(fadadaResultFuture);
        String result = fadadaResult.getResult();
        String code = fadadaResult.getCode();
        if ("success".equals(result) && "1000".equals(code)) {
            String customerId = fadadaResult.getCustomerId();
            getSelfProxy().fadadaAuthSuccessResultDeal(userId, customerId);
            return customerId;
        } else {
            return null;
        }
    }

    @Transactional
    public void fadadaAuthSuccessResultDeal(String userId, String fadadaCacertId) {
        UserAuthorizationInfo oldUserAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);

        //保存用户授权法大大信息
        Date now = new Date();
        if (oldUserAuthorizationInfo == null) { //没有则新增
            UserAuthorizationInfo userAuthorizationInfo = new UserAuthorizationInfo();
            userAuthorizationInfo.setUserId(userId);
            userAuthorizationInfo.setFadadaCacertId(fadadaCacertId);
            userAuthorizationInfo.setCreateTime(now);
            userAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.insertSelective(userAuthorizationInfo);
        } else {
            oldUserAuthorizationInfo.setFadadaCacertId(fadadaCacertId);
            oldUserAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.updateByPrimaryKeySelective(oldUserAuthorizationInfo);
        }

        DataStatus dataStatus = new DataStatus();
        dataStatus.setUserId(userId);
        dataStatus.setDataType(UserDataTypeEnum.FADADA_AUTHORIZE.getValue());
        dataStatus.setDataStatus(UserDataStatusEnum.FadadaStatus.PASS_CERTIFIED.getStatus());
        dataStatus.setAuthTime(now);
        dataStatus.setUpdateTime(now);
        userStatusService.saveDataStatusByUserIdAndType(dataStatus);
    }

    /**
     * 企业法大大授权编码保存
     *
     * @param organizationInfo
     * @param fadadaCacertId
     */
    @Transactional
    public void fadadaAuthEnterSuccessResult(OrganizationInfo organizationInfo, String fadadaCacertId) {
        //保存用户授权法大大信息
        log.info("保存用户授权法大大信息organizationInfo={},fadadaCacertId={}", JSONObject.toJSONString(organizationInfo), fadadaCacertId);
        Date now = new Date();
        organizationInfo.setFadadaCacertId(fadadaCacertId);
        organizationInfo.setUpdateTime(now);
        organizationInfoMapperExt.updateByPrimaryKeySelective(organizationInfo);

    }

    @Transactional
    public void saveUserZhiMaInfo(String userId, Integer zhimaScore, String failureReason, UserDataStatusEnum.ZhimaCreditStatus statusEnum, Date authTime) {
        UserAuthorizationInfo oldUserAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);

        //保存用户芝麻授权信息
        Date now = new Date();
        if (oldUserAuthorizationInfo == null) { //没有则新增
            UserAuthorizationInfo userAuthorizationInfo = new UserAuthorizationInfo();
            userAuthorizationInfo.setUserId(userId);
            userAuthorizationInfo.setZhimaScore(zhimaScore);
            userAuthorizationInfo.setZhimaFailureReason(failureReason);
            userAuthorizationInfo.setCreateTime(now);
            userAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.insertSelective(userAuthorizationInfo);
        } else {
            oldUserAuthorizationInfo.setZhimaScore(zhimaScore);
            oldUserAuthorizationInfo.setZhimaFailureReason(failureReason);
            oldUserAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.updateByPrimaryKeySelective(oldUserAuthorizationInfo);
        }

        DataStatus oldDataStatus = dataStatusMapper.selectByUserIdAndType(userId, UserDataTypeEnum.ZHIMA_AUTHORIZE.getValue());
        //保存用户资料或认证状态-芝麻授权状态
        if (oldDataStatus == null) { //没有则新增
            DataStatus dataStatus = new DataStatus();
            dataStatus.setId(snowflakeIdWorker.nextId());
            dataStatus.setUserId(userId);
            dataStatus.setDataType(UserDataTypeEnum.ZHIMA_AUTHORIZE.getValue());
            dataStatus.setDataStatus(statusEnum.getStatus());
            dataStatus.setCreateTime(now);
            dataStatus.setUpdateTime(now);
            dataStatus.setAuthTime(authTime);
            dataStatusMapper.insertSelective(dataStatus);
        } else {
            oldDataStatus.setUserId(userId);
            oldDataStatus.setDataType(UserDataTypeEnum.ZHIMA_AUTHORIZE.getValue());
            oldDataStatus.setDataStatus(statusEnum.getStatus());
            oldDataStatus.setUpdateTime(now);
            oldDataStatus.setAuthTime(authTime);
            dataStatusMapper.updateByPrimaryKeySelective(oldDataStatus);
        }
    }

    /**
     * 保存社保信息
     *
     * @param userId
     * @param socialSecurityAuthCity
     * @param statusEnum
     */
    @Transactional
    public void saveUserSocialInfo(String userId, String socialSecurityAuthCity, UserDataStatusEnum.SocialSecurityStatus statusEnum, Date authTime, UserDataTypeEnum userDataTypeEnum) {
        if (userDataTypeEnum != UserDataTypeEnum.SOCIAL_SECURITY_OPERATOR_AUTHORIZE && userDataTypeEnum != UserDataTypeEnum.R360_SOCIAL_SECURITY_OPERATOR_AUTHORIZE) {
            log.error("保存社保信息类型错误：" + userDataTypeEnum);
            return;
        }

        UserAuthorizationInfo oldUserAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);

        //保存用户社保授权信息
        Date now = new Date();
        if (oldUserAuthorizationInfo == null) {
            UserAuthorizationInfo userAuthorizationInfo = new UserAuthorizationInfo();
            userAuthorizationInfo.setUserId(userId);
            userAuthorizationInfo.setSocialSecurityAuthCity(socialSecurityAuthCity);
            userAuthorizationInfo.setCreateTime(now);
            userAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.insertSelective(userAuthorizationInfo);
        } else {
            oldUserAuthorizationInfo.setSocialSecurityAuthCity(socialSecurityAuthCity);
            oldUserAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.updateByPrimaryKeySelective(oldUserAuthorizationInfo);
        }

        DataStatus oldDataStatus = dataStatusMapper.selectByUserIdAndType(userId, userDataTypeEnum.getValue());

        //保存用户资料或认证状态-社保授权状态
        if (oldDataStatus == null) { //没有则新增
            DataStatus dataStatus = new DataStatus();
            dataStatus.setId(snowflakeIdWorker.nextId());
            dataStatus.setUserId(userId);
            dataStatus.setDataType(userDataTypeEnum.getValue());
            dataStatus.setDataStatus(statusEnum.getStatus());
            dataStatus.setCreateTime(now);
            dataStatus.setUpdateTime(now);
            dataStatus.setAuthTime(authTime);
            dataStatusMapper.insertSelective(dataStatus);
        } else {
            oldDataStatus.setUserId(userId);
            oldDataStatus.setDataType(userDataTypeEnum.getValue());
            oldDataStatus.setDataStatus(statusEnum.getStatus());
            oldDataStatus.setUpdateTime(now);
            oldDataStatus.setAuthTime(authTime);
            dataStatusMapper.updateByPrimaryKeySelective(oldDataStatus);
        }
    }

    /**
     * 保存用户京东登录名信息
     *
     * @param userId
     * @param jdLoginname
     */
    @Transactional
    public void saveJdInfo(String userId, String jdLoginname) {

        UserAuthorizationInfo oldUserAuthorizationInfo = userAuthorizationInfoMapper.selectByPrimaryKey(userId);

        //保存用户社保授权信息
        Date now = new Date();
        if (oldUserAuthorizationInfo == null) {
            UserAuthorizationInfo userAuthorizationInfo = new UserAuthorizationInfo();
            userAuthorizationInfo.setUserId(userId);
            userAuthorizationInfo.setJdLoginName(jdLoginname);
            userAuthorizationInfo.setCreateTime(now);
            userAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.insertSelective(userAuthorizationInfo);
        } else {
            oldUserAuthorizationInfo.setJdLoginName(jdLoginname);
            oldUserAuthorizationInfo.setUpdateTime(now);
            userAuthorizationInfoMapper.updateByPrimaryKeySelective(oldUserAuthorizationInfo);
        }
    }

    private UserAuthorizationInfoService getSelfProxy() {
        return (UserAuthorizationInfoService) AopContext.currentProxy();
    }

    /**
     * 通过用户id查询用户法大大授权信息
     *
     * @param userId
     * @return
     */
    public UserAuthorizationInfoDTO selectByUserId(String userId) {
        UserAuthorizationInfo userAuthorizationInfo = userAuthorizationInfoMapper.selectById(userId);
        UserAuthorizationInfoDTO userAuthorizationInfoDTO = null;
        if (userAuthorizationInfo != null) {
            userAuthorizationInfoDTO = new UserAuthorizationInfoDTO();
            BeanUtils.copyProperties(userAuthorizationInfo, userAuthorizationInfoDTO);
        }
        return userAuthorizationInfoDTO;
    }
}
